package com.gzhryc.shared_device.cdcz.core.protocol.v1;

import com.gzhryc.common.IDTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.shared_device.cdcz.core.CDCZConstants;
import com.gzhryc.shared_device.cdcz.core.ICDCZNetworkEventListener;
import com.gzhryc.shared_device.cdcz.core.models.*;
import com.gzhryc.shared_device.cdcz.core.protocol.v1.models.BKVData;
import com.gzhryc.shared_device.cdcz.core.protocol.v1.models.PlugBKVData;
import com.gzhryc.shared_device.cdcz.core.protocol.v1.models.PlugStateData;
import com.gzhryc.shared_device.iot.code.IIOTLogServer;
import com.gzhryc.shared_device.iot.code.dao.db.IOTLogsRecord;
import com.gzhryc.shared_device.iot.code.dao.enums.ELogType;
import com.gzhryc.shared_device.iot.core.IOTClientEvent;
import com.gzhryc.shared_device.iot.core.IOTClientEventListener;
import com.gzhryc.shared_device.iot.core.IOTMessage;

import java.util.ArrayList;

public class V1_CDCZ_IOTClientEventListener implements IOTClientEventListener {

    static Logger log = Logger.getLogger(V1_CDCZ_IOTClientEventListener.class);

    private final IIOTLogServer logServer;
    private final ICDCZNetworkEventListener eventListener;

    public V1_CDCZ_IOTClientEventListener(IIOTLogServer logServer, ICDCZNetworkEventListener eventListener){
        this.logServer = logServer;
        this.eventListener = eventListener;
    }

    @Override
    public void active(IOTClientEvent event) {

    }

    @Override
    public void receiveMessage(IOTClientEvent event) {
        V1_CDCZ_IOTMessage message = null;
        try {
            byte[] bytes = event.getMessage().getBytes();
            message = new V1_CDCZ_IOTMessage(bytes);
            message.setDeviceSn(event.getDeviceSn());
            message.setTopic(event.getMessage().getTopic());

            //记录日志
            IOTLogsRecord eventEntity = new IOTLogsRecord();
            eventEntity.setType(ELogType.DeviceLog.name());
            eventEntity.setIotId(event.getClient().getIOTNote().getId());
            eventEntity.setDeviceSn(message.getDeviceSn());
            eventEntity.setIotTopic(message.getTopic());
            eventEntity.setContent(message.byte2Hex());
            eventEntity.setProtocolType(CDCZConstants.ProtocolTypeV1);
            eventEntity.setCommand(message.getCmd());
            eventEntity.setMsgId(message.getMessageId());
            logServer.send(eventEntity);
        } catch (Exception e) {
            log.error("接收IOT信息错误，内容：{{1}}", e, event.getMessage().byte2Hex());

            //记录日志
            IOTLogsRecord eventEntity = new IOTLogsRecord();
            eventEntity.setType(ELogType.DeviceLog.name());
            eventEntity.setIotId(event.getClient().getIOTNote().getId());
            eventEntity.setDeviceSn(event.getDeviceSn());
            eventEntity.setIotTopic(event.getMessage().getTopic());
            eventEntity.setContent(event.getMessage().byte2Hex());
            eventEntity.setMsgId("---");
            eventEntity.setProtocolType(CDCZConstants.ProtocolTypeV1);
            eventEntity.setCommand("解析失败");
            logServer.send(eventEntity);
        }
        if (message != null) {
            try {
                if (V1_CDCZConstants.CMD_HEARTBEAT.equals(message.getCmd())) {
                    //心跳
                    CDCZHeartbeatNotify notify = new CDCZHeartbeatNotify();
                    notify.setDeviceSn(message.getDeviceSn());
                    notify.setRssi(message.getBKVIntegerValue(V1_CDCZConstants.KEY_CSQ));
                    notify.setMcuTemperature(message.getBKVDoubleValue(V1_CDCZConstants.KEY_MCU_TEMPERATURE, 0));

                    for (int i = 1; i <= 10; i++) {
                        PlugBKVData plugBKVData = message.getPlugInfo(i);
                        if (plugBKVData != null) {
                            if (notify.getPlugInfoList() == null) {
                                notify.setPlugInfoList(new ArrayList<>());
                            }
                            CDCZPlugInfo info = new CDCZPlugInfo();
                            info.setSlotNum(i);
                            info.setOverloadState(V1_CDCZPlugStateUtils.getOverloadState(plugBKVData));
                            info.setWorkState(plugBKVData.getWorkState());
                            info.setPowerState(plugBKVData.getOverloadState());
                            info.setTemperatureState(V1_CDCZPlugStateUtils.geTemperatureState(plugBKVData));
                            info.setNowPower(plugBKVData.getNowPower());
                            info.setNowCurrent(plugBKVData.getNowCurrent());
                            info.setChargedTime(plugBKVData.getChargeTime());   //已充时间
                            info.setElectricity(plugBKVData.getElectricity());  //已充电量
                            notify.getPlugInfoList().add(info);
                        }
                    }

                    this.eventListener.heartbeat(event.getClient(),notify);

                    V1_CDCZ_IOTCloudMessage cloudMessage = new V1_CDCZ_IOTCloudMessage();
                    cloudMessage.setCmd(message.getCmd());
                    cloudMessage.setMessageId(message.getMessageId());
                    cloudMessage.getBkvDataList().add(new BKVData(V1_CDCZConstants.KEY_TIME, IDTools.getTimestampSecondID()));
                    cloudMessage.setDeviceSn(event.getDeviceSn());
                    cloudMessage.setTopic("/" + event.getDeviceSn() + "/user/get");
                    event.getClient().send(cloudMessage);

                } else if (V1_CDCZConstants.CMD_SEARCH_SLOT.equals(message.getCmd())) {
                    CDCZSearchResultNotify notify = new CDCZSearchResultNotify();
                    notify.setDeviceSn(message.getDeviceSn());
                    notify.setMcuTemperature(message.getBKVDoubleValue(V1_CDCZConstants.KEY_MCU_TEMPERATURE, 0));

                    for (int i = 1; i <= 10; i++) {
                        PlugBKVData plugBKVData = message.getPlugInfo(i);
                        if (plugBKVData != null) {
                            if (notify.getPlugInfoList() == null) {
                                notify.setPlugInfoList(new ArrayList<>());
                            }
                            CDCZPlugInfo info = new CDCZPlugInfo();
                            info.setSlotNum(i);
                            info.setOverloadState(V1_CDCZPlugStateUtils.getOverloadState(plugBKVData));
                            info.setWorkState(plugBKVData.getWorkState());
                            info.setPowerState(plugBKVData.getOverloadState());
                            info.setTemperatureState(V1_CDCZPlugStateUtils.geTemperatureState(plugBKVData));
                            info.setNowPower(plugBKVData.getNowPower());
                            info.setNowCurrent(plugBKVData.getNowCurrent());
                            info.setChargedTime(plugBKVData.getChargeTime());
                            info.setElectricity(plugBKVData.getElectricity());
                            notify.getPlugInfoList().add(info);
                        }
                    }

                    this.eventListener.searchResult(event.getClient(),notify);

                }else if (V1_CDCZConstants.CMD_CONTROL.equals(message.getCmd())) {
                    //启动响应
                    CDCZChargeStartupResultNotify notify = new CDCZChargeStartupResultNotify();
                    notify.setDeviceSn(message.getDeviceSn());
                    notify.setMessageId(message.getMessageId());
                    //notify.setSlotNum(message.getBKVIntegerValue(V1_CDCZConstants.KEY_PLUG_NUM));
                    Integer result = message.getBKVIntegerValue(V1_CDCZConstants.KEY_ACK);
                    if(result == 1) {
                        notify.setResultCode(CDCZExecuteResult.SUCCESS);
                    }else{
                        notify.setResultCode(CDCZExecuteResult.FAIL);
                    }

                    this.eventListener.chargeStartupResult(event.getClient(),notify);

                } else if (V1_CDCZConstants.CMD_CHARGE_END.equals(message.getCmd())) {
                    Integer slotNum = message.getBKVIntegerValue(V1_CDCZConstants.KEY_PLUG_NUM);
                    //充电结束
                    CDCZChargeCloseNotify notify = new CDCZChargeCloseNotify();
                    notify.setDeviceSn(message.getDeviceSn());
                    notify.setSlotNum(slotNum);

                    notify.setNowPower(message.getBKVDoubleValue(V1_CDCZConstants.KEY_POWER, 1));
                    notify.setNowCurrent(message.getBKVDoubleValue(V1_CDCZConstants.KEY_CURRENT, 3));
                    notify.setElectricity(message.getBKVDoubleValue(V1_CDCZConstants.KEY_PLUG_ELECTRICITY, 3));
                    notify.setChargedTime(message.getBKVIntegerValue(V1_CDCZConstants.KEY_PLUG_CHARGE_TIME));
                    notify.setChargeFinishTime(message.getBKVHexValue(V1_CDCZConstants.KEY_CHARGE_FINISH_TIME));

                    BKVData bkvData = message.getBKVDataMap().get(V1_CDCZConstants.KEY_PLUG_SLOT_STATE);
                    PlugStateData plugStateData = new PlugStateData(bkvData.getHexValue());
                    notify.setWorkState(plugStateData.getWorkState());

                    this.eventListener.chargeClose(notify);

                    V1_CDCZ_IOTCloudMessage cloudMessage = new V1_CDCZ_IOTCloudMessage();
                    cloudMessage.setCmd(message.getCmd());
                    cloudMessage.setMessageId(message.getMessageId());
                    cloudMessage.getBkvDataList().add(new BKVData(V1_CDCZConstants.KEY_TIME, IDTools.getTimestampSecondID()));
                    cloudMessage.getBkvDataList().add(new BKVData(V1_CDCZConstants.KEY_ACK, "1"));
                    cloudMessage.setDeviceSn(event.getDeviceSn());
                    cloudMessage.setTopic("/" + event.getDeviceSn() + "/user/get");
                    event.getClient().send(cloudMessage);

                } else if (V1_CDCZConstants.CMD_START_UP.equals(message.getCmd())) {
                    //设备启动
                    CDCZOnlineNotify notify = new CDCZOnlineNotify();
                    notify.setDeviceSn(message.getDeviceSn());
                    notify.setVersion(message.getBKVStringValue(V1_CDCZConstants.KEY_VERSION));
                    //notify.setIccid(message.getBKVHexValue(V1_CDCZConstants.KEY_SIM_ICCID));
                    notify.setIccid(message.getBKVStringValue(V1_CDCZConstants.KEY_SIM_ICCID));
                    notify.setRssi(message.getBKVIntegerValue(V1_CDCZConstants.KEY_CSQ));
                    notify.setType(1);

                    if (this.eventListener.online(notify)) {
                        V1_CDCZ_IOTCloudMessage cloudMessage = new V1_CDCZ_IOTCloudMessage();
                        cloudMessage.setCmd(message.getCmd());
                        cloudMessage.setMessageId(message.getMessageId());
                        cloudMessage.getBkvDataList().add(new BKVData(V1_CDCZConstants.KEY_TIME, IDTools.getTimestampSecondID()));
                        cloudMessage.setDeviceSn(event.getDeviceSn());
                        cloudMessage.setTopic("/" + event.getDeviceSn() + "/user/get");
                        event.getClient().send(cloudMessage);
                    }
                } else if (V1_CDCZConstants.CMD_ABNORMAL.equals(message.getCmd())) {
                    //卡槽异常上报
                    CDCZPlugAbnormalNotify notify = new CDCZPlugAbnormalNotify();
                    notify.setDeviceSn(message.getDeviceSn());
                    notify.setMcuTemperature(message.getBKVDoubleValue(V1_CDCZConstants.KEY_MCU_TEMPERATURE, 0));

                    for (int i = 1; i <= 10; i++) {
                        PlugBKVData plugBKVData = message.getPlugInfo(i);
                        if (plugBKVData != null) {
                            if (notify.getPlugInfoList() == null) {
                                notify.setPlugInfoList(new ArrayList<>());
                            }
                            CDCZPlugInfo info = new CDCZPlugInfo();
                            info.setSlotNum(i);
                            info.setOverloadState(V1_CDCZPlugStateUtils.getOverloadState(plugBKVData));
                            info.setWorkState(plugBKVData.getWorkState());
                            info.setPowerState(plugBKVData.getOverloadState());
                            info.setTemperatureState(V1_CDCZPlugStateUtils.geTemperatureState(plugBKVData));
                            info.setNowPower(plugBKVData.getNowPower());
                            info.setNowCurrent(plugBKVData.getNowCurrent());
                            info.setChargedTime(plugBKVData.getChargeTime());
                            info.setElectricity(plugBKVData.getElectricity());
                            notify.getPlugInfoList().add(info);
                        }
                    }
                    this.eventListener.slotAbnormal(notify);
                }else if (V1_CDCZConstants.CMD_RESTART.equals(message.getCmd())) {
                    //重启命令响应
                    CDCZRestartResultNotify notify = new CDCZRestartResultNotify();
                    notify.setDeviceSn(message.getDeviceSn());
                    notify.setResultCode(message.getBKVIntegerValue(V1_CDCZConstants.KEY_ACK));

                    this.eventListener.restartResult(notify);
                }else if (V1_CDCZConstants.CMD_FIRMWARE_DOWNLOAD.equals(message.getCmd())) {
                    CDCZUpgradeNotify notify = new CDCZUpgradeNotify();
                    notify.setDeviceSn(message.getDeviceSn());
                    notify.setType(2);  //下载
                    notify.setState(message.getBKVIntegerValue(V1_CDCZConstants.KEY_ACK));

                    this.eventListener.upgrade(event.getClient(),notify);
                }else if (V1_CDCZConstants.CMD_FIRMWARE_UP.equals(message.getCmd())) {
                    CDCZUpgradeNotify notify = new CDCZUpgradeNotify();
                    notify.setDeviceSn(message.getDeviceSn());
                    notify.setType(1);      //升级
                    notify.setState(message.getBKVIntegerValue(V1_CDCZConstants.KEY_ACK));

                    this.eventListener.upgrade(event.getClient(),notify);
                }
            } catch (Exception e) {
                log.error("接收IOT信息错误，主题：{{1}}，原始报文：{{2:json}}", e, message.getTopic(),message.byte2Hex());
            }
        }
    }

    @Override
    public void stateChange(IOTClientEvent event) {
        log.info("～～～设备上下线变更～～～");
    }

    @Override
    public void sendMessage(IOTMessage msg, Long iotId, String topic) {
        //记录日志
        IOTLogsRecord eventEntity = new IOTLogsRecord();
        eventEntity.setType(ELogType.CloudLog.name());
        eventEntity.setIotId(iotId);
        eventEntity.setDeviceSn(msg.getDeviceSn());
        eventEntity.setIotTopic(topic);
        eventEntity.setContent(msg.byte2Hex());
        eventEntity.setMsgId(msg.getMessageId());
        eventEntity.setProtocolType(CDCZConstants.ProtocolTypeV1);
        eventEntity.setCommand(msg.getCmd());
        logServer.send(eventEntity);
    }
}
